home *** CD-ROM | disk | FTP | other *** search
- /* Amiga terminal control routines.
- Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
-
- This file is part of GNU Emacs.
-
- GNU Emacs is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- GNU Emacs is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Emacs; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/time.h>
- #include "config.h"
- #include "termhooks.h"
- #include "termchar.h"
- #include "termopts.h"
- #include "lisp.h"
- #include "frame.h"
-
- #ifdef USE_PROTOS
- #include "protos.h"
- #endif
-
- #ifdef GENPROTO
- extern void *Aframe_raise_lower; /* CHFIXME */
- #endif
-
- /* internal state */
-
- /* nonzero means supposed to write text in standout mode. */
- static int Astandout_requested;
-
- static int Astandout_mode; /* Nonzero when in standout mode. */
-
- static char tens[100] = {
- '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
- '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
- '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
- '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
- '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
- '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
- '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
- '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
- '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
- '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
- };
-
- static char ones[100] = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- };
-
- #define addnum(str, num) if (num < 100) \
- { *--str = ones[num]; *--str = tens[num]; } \
- else do { *--str = '0' + num % 10; num /= 10; } while (num != 0)
-
- static Abackground_highlight ();
- static Aturn_off_highlight ();
-
-
- /* Cursor motion stuff (from cm.c) */
- static int curX, curY;
-
- /* Move cursor to absolute position, specified origin 0 */
-
- static int
- Acursor_to (int row, int col)
- {
- char buf[32], *pos = buf + 32;
-
- if (curY == row && curX == col)
- return;
-
- curX = col; curY = row;
- *--pos = 'H';
- col = col + 1; row = row + 1;
- addnum(pos, col);
- *--pos = ';';
- addnum(pos, row);
- *--pos = (char) 0x9b;
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- emacs_output(selected_frame, pos, buf + 32 - pos);
- if (pos < buf) abort();
- }
-
-
- Aring_bell ()
- {
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- emacs_output(selected_frame, "\07", 1);
- }
-
- Aset_terminal_modes ()
- {
- }
-
- Areset_terminal_modes ()
- {
- Aturn_off_highlight ();
- }
-
- int
- Aupdate_begin (FRAME_PTR f)
- {
- /* Hide cursor */
- emacs_output(f, "\x9b\x30\x20\x70", 4);
- }
-
- int
- Aupdate_end (FRAME_PTR f)
- {
- Abackground_highlight ();
- Astandout_requested = 0;
- emacs_output(f, "\x9b\x20\x70", 3); /* Show cursor */
- }
-
-
- /* Handle highlighting when TN_standout_width (termcap sg) is not specified.
- In these terminals, output is affected by the value of standout
- mode when the output is written.
-
- These functions are called on all terminals, but do nothing
- on terminals whose standout mode does not work that way. */
-
- static Aturn_off_highlight ()
- {
- if (Astandout_mode)
- {
- extern int background, foreground;
- extern int inverse_fill_pen, inverse_text_pen;
- int b = background + 40, f = foreground + 30;
- if(inverse_fill_pen < 8 && inverse_text_pen < 8)
- {
- char buf[32], *pos = buf + 32;
- /* UnDo inverse fill */
- *--pos = '\0';
- *--pos = 'm';
- addnum(pos, b);
- *--pos = ';';
- /* UnDo inverse text */
- addnum(pos, f);
- *--pos = (char) 0x9b;
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- emacs_output(selected_frame, pos, buf + 32 - pos);
- }
- else
- {
- emacs_output(selected_frame, "\x9b""27m", 4);
- }
- }
- Astandout_mode = 0;
- }
-
- static Aturn_on_highlight ()
- {
- if (!Astandout_mode)
- {
- extern int inverse_fill_pen, inverse_text_pen;
- int b = inverse_fill_pen + 40, f = inverse_text_pen + 30;
- if(inverse_fill_pen < 8 && inverse_text_pen < 8)
- {
- char buf[32], *pos = buf + 32;
- /* Do inverse fill */
- *--pos = '\0';
- *--pos = 'm';
- addnum(pos, b);
- *--pos = ';';
-
- /* Do inverse text */
- addnum(pos, f);
- *--pos = (char) 0x9b;
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- emacs_output(selected_frame, pos, buf + 32 - pos);
- }
- else
- {
- emacs_output(selected_frame, "\x9b\x37m", 3);
- }
- }
- Astandout_mode = 1;
- }
-
- /* Set standout mode to the state it should be in for
- empty space inside windows. What this is,
- depends on the user option inverse-video. */
-
- static Abackground_highlight ()
- {
- if (inverse_video)
- Aturn_on_highlight ();
- else
- Aturn_off_highlight ();
- }
-
- /* Set standout mode to the mode specified for the text to be output. */
-
- static
- Ahighlight_if_desired ()
- {
- if (!inverse_video == !Astandout_requested)
- Aturn_off_highlight ();
- else
- Aturn_on_highlight ();
- }
-
- /* External interface to control of standout mode.
- Call this when about to modify line at position VPOS
- and not change whether it is highlighted. */
-
- Areassert_line_highlight (highlight, vpos)
- int highlight;
- int vpos;
- {
- Astandout_requested = highlight;
- }
-
- /* Call this when about to modify line at position VPOS
- and change whether it is highlighted. */
-
- Achange_line_highlight (new_highlight, vpos, first_unused_hpos)
- int new_highlight, vpos, first_unused_hpos;
- {
- Astandout_requested = new_highlight;
-
- cursor_to (vpos, 0);
-
- Abackground_highlight ();
- clear_end_of_line (first_unused_hpos);
- reassert_line_highlight (new_highlight, curY);
- }
-
- /* Erase operations */
-
- /* clear from cursor to end of screen */
- Aclear_to_end ()
- {
- Abackground_highlight ();
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- emacs_output(selected_frame, "\x9bJ", 2);
- }
-
- /* Clear entire frame */
-
- static int
- Aclear_frame (FRAME_PTR f)
- {
- Abackground_highlight ();
- emacs_output(f, "\f", 1);
- curX = curY = 0;
- }
-
- /* Clear to end of line, but do not clear any standout marker.
- Assumes that the cursor is positioned at a character of real text,
- which implies it cannot be before a standout marker
- unless the marker has zero width.
-
- Note that the cursor may be moved. */
-
- Aclear_end_of_line (first_unused_hpos)
- int first_unused_hpos;
- {
- if (curX >= first_unused_hpos)
- return;
-
- Abackground_highlight ();
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- emacs_output(selected_frame, "\x9bK", 2);
- }
-
- static int
- Aoutput_glyphs (string, len)
- register GLYPH *string;
- int len;
- {
- Ahighlight_if_desired ();
-
- curX += len;
- emacs_output_glyphs(selected_frame, string, len);
- }
-
- /* If start is zero, insert blanks instead of a string at start */
-
- static int
- Ainsert_glyphs (start, len)
- register GLYPH *start;
- int len;
- {
- char buf[32], *pos = buf + 32;
-
- Ahighlight_if_desired ();
-
- *--pos = '@';
- addnum(pos, len);
- *--pos = (char) 0x9b;
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- emacs_output(selected_frame, pos, buf + 32 - pos);
- if (pos < buf) abort();
- if (start) emacs_output_glyphs(selected_frame, start, len);
- }
-
- static int
- Adelete_glyphs (n)
- register int n;
- {
- char buf[32], *pos = buf + 32;
-
- *--pos = 'P';
- addnum(pos, n);
- *--pos = (char) 0x9b;
- emacs_output(selected_frame, pos, buf + 32 - pos);
- if (pos < buf) abort();
- }
-
- /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
-
- Ains_del_lines (vpos, n)
- int vpos, n;
- {
- register int i = n > 0 ? n : -n;
- char buf[32], *pos = buf + 32;
-
- if (n > 0)
- {
- i = n;
- *--pos = 'L';
- }
- else
- {
- i = -n;
- *--pos = 'M';
- }
- if (vpos + i >= FRAME_HEIGHT (selected_frame)) return;
-
- cursor_to (vpos, 0);
- Abackground_highlight ();
- addnum(pos, i);
- *--pos = (char) 0x9b;
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
-
- emacs_output(selected_frame, pos, buf + 32 - pos);
- if (pos < buf) abort();
- }
-
- #if 0 /* CHFIXME */
- Acalculate_costs (extra, costvec, ncostvec)
- int extra;
- int *costvec, *ncostvec;
- {
- line_ins_del(selected_frame, 2, 40, extra, 0, costvec, ncostvec);
- }
- #endif
-
- Aset_terminal_window (int size)
- {
- }
-
- /* Return the current position of the mouse.
-
- Set *f to the frame the mouse is in, or zero if the mouse is in no
- Emacs frame. If it is set to zero, all the other arguments are
- garbage.
-
- If the motion started in a scroll bar, set *bar_window to the
- scroll bar's window, *part to the part the mouse is currently over,
- *x to the position of the mouse along the scroll bar, and *y to the
- overall length of the scroll bar.
-
- Otherwise, set *bar_window to Qnil, and *x and *y to the column and
- row of the character cell the mouse is over.
-
- Set *time to the time the mouse was at the returned position.
-
- This should clear mouse_moved until the next motion
- event arrives. */
- extern int mouse_moved;
-
- static void
- Amouse_position(FRAME_PTR *f,
- Lisp_Object *bar_window,
- enum scroll_bar_part *part,
- Lisp_Object *x, Lisp_Object *y,
- unsigned long *time)
- {
- struct timeval tv;
- int an_x, an_y;
-
- #ifdef MULTI_FRAME
- CHFIXME
- #endif
- get_mouse_char_pos(selected_frame, &an_x, &an_y);
- if(x >= 0 && y >= 0) /* CHFIXME: always report ? */
- {
- *f = selected_frame; /* CHFIXME: ok for MULTI_FRAME ? */
- *bar_window = Qnil;
- *x = make_number (an_x);
- *y = make_number (an_y);
- gettimeofday (&tv, NULL);
- *time = tv.tv_usec;
- }
- else
- {
- *f = NULL;
- }
- mouse_moved = 0;
- }
- /* Change from withdrawn state to mapped state,
- or deiconify. */
-
- void
- x_make_frame_visible (FRAME_PTR f)
- {
- /* CHFIXME: add deiconify call! */
- }
-
- amiga_term_init ()
- {
- must_write_spaces = FALSE;
- min_padding_speed = 0;
- memory_below_frame = FALSE; /* we don't remember what scrolls
- off the bottom */
- meta_key = 2; /* 1 if should obey 0200 bit in input chars as "Meta", 2 if should
- keep 0200 bit in input chars. 0 to ignore the 0200 bit. */
-
- scroll_region_ok = TRUE; /* CHFIXME: test */ /* we'll scroll partial frames */
- scroll_region_ok = FALSE; /* we don\'t scroll partial frames */
- line_ins_del_ok = TRUE; /* CHFIXME: test */
- line_ins_del_ok = FALSE; /* much cleaner display when FALSE -ch3/19/93. */
- char_ins_del_ok = FALSE;
- fast_clear_end_of_line = TRUE;
- no_redraw_on_reenter = FALSE;
-
- clear_frame_hook = Aclear_frame;
- clear_end_of_line_hook = Aclear_end_of_line;
- clear_to_end_hook = Aclear_to_end;
- ins_del_lines_hook = Ains_del_lines;
- change_line_highlight_hook = Achange_line_highlight;
-
- insert_glyphs_hook = Ainsert_glyphs;
- write_glyphs_hook = Aoutput_glyphs;
- delete_glyphs_hook = Adelete_glyphs;
-
- ring_bell_hook = Aring_bell;
- reset_terminal_modes_hook = Areset_terminal_modes;
- set_terminal_modes_hook = Aset_terminal_modes;
- update_begin_hook = Aupdate_begin;
- update_end_hook = Aupdate_end;
- set_terminal_window_hook = Aset_terminal_window;
- /* read_socket_hook ? */ /* CHFIXME */
- /* frame_up_to_date_hook */
- cursor_to_hook = Acursor_to;
- reassert_line_highlight_hook = Areassert_line_highlight;
- raw_cursor_to_hook = Acursor_to; /* CHFIXME, correct ? */
-
- mouse_position_hook = Amouse_position;
- /*
- frame_rehighlight_hook = XTframe_rehighlight;
- */
- frame_raise_lower_hook = Aframe_raise_lower;
- /*
- set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
- */
- #ifdef USE_SCROLL_BARS
- condemn_scroll_bars_hook = Acondemn_scroll_bars;
- redeem_scroll_bar_hook = Aredeem_scroll_bar;
- judge_scroll_bars_hook = Ajudge_scroll_bars;
- #endif
- #if 0
- /* dont_calculate_costs = 1; try to use it CHFIXME */
- #else
- dont_calculate_costs = 0;
- #endif
-
- #if 0 /* CHFIXME */
- calculate_costs_hook = Acalculate_costs;
- #endif
-
- /* Get screen size from system, or else from somewhere ... */
-
- #ifdef MULTI_FRAME
- you lose
- #endif
- get_frame_size (&FRAME_WIDTH(selected_frame), &FRAME_HEIGHT(selected_frame));
- /* Random defaults to avoid any problems */
- if (FRAME_WIDTH(selected_frame) <= 0) FRAME_WIDTH(selected_frame) = 80;
- if (FRAME_HEIGHT(selected_frame) <= 0) FRAME_HEIGHT(selected_frame) = 23;
-
- init_baud_rate ();
- FRAME_CAN_HAVE_SCROLL_BARS (selected_frame) = 0; /* CHFIXME */
- FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame) = 0;
-
-
- /* CHFIXME: move init glyphs stuff here ? */
- }
-